home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * patchinfo.c: Functions for initializing, filling, printing, and
- * destroying PATCHINFO structures.
- * A part of OberSuite for the Commodore Amiga.
- *
- * Author: Daniel Barrett, barrett@cs.umass.edu.
- * Version: 1.0.
- * Copyright: None! This program is in the Public Domain.
- * Please share it with others.
- ***************************************************************************/
-
- #include "decl.h"
- #include "midi.h"
- #include "oberheim.h"
- #include "patchinfo.h"
-
- /*****************************************************************************
- * Initializing patchinfo data.
- *****************************************************************************/
-
- void InitPatchInfo(PATCHINFO *pi)
- {
- pi->actualSize = (long)0;
- pi->data = NULL;
- pi->firstSingleOffset = (long)0;
- pi->mode = (UBYTE)0;
- pi->nameOffset = (long)0;
- pi->numPatches = (long)0;
- pi->numSinglesInside = (long)0;
- pi->patchNum = (UBYTE)0;
- pi->rightSize = (long)0;
- pi->source = 0;
-
- strcpy(pi->instrument, "UNKNOWN");
- strcpy(pi->modeName, "UNKNOWN");
- }
-
-
- /*****************************************************************************
- * Allocate patchinfo data.
- *****************************************************************************/
-
- BOOL AllocPatchInfo(PATCHINFO *pi)
- {
- return((BOOL)
- (pi->data = (UBYTE *)malloc(pi->rightSize * pi->numPatches)));
- }
-
-
- /*****************************************************************************
- * Freeing patchinfo data.
- *****************************************************************************/
-
- void FreePatchInfo(PATCHINFO *pi)
- {
- if (pi->data)
- free(pi->data);
- pi->data = NULL;
- }
-
-
- /*****************************************************************************
- * Printing patchinfo data (for diagnostic purposes).
- *****************************************************************************/
-
- /*
- * Print information about the patch data found at address
- * pi->data + offset. The data MUST be valid before calling this function.
- */
-
- void PrintPatchInfo(PATCHINFO *pi, long offset)
- {
- int num;
-
- if ((pi->data) && (pi->rightSize == pi->actualSize))
- {
- num = pi->data[offset + BYTE_PATCHNUMBER];
- printf("%s %s patch %02d: ", pi->instrument, pi->modeName,
- num);
- PrintPatchName(pi->data + offset, pi->nameOffset);
-
- if (pi->mode == MODE_MULTI)
- PrintSinglesInMulti(pi->data + offset,
- pi->numSinglesInside, pi->firstSingleOffset);
-
- printf("\n");
- }
- else
- fprintf(stderr, "No data to print.\n");
- }
-
-
- /*
- * Print the name of the given patch. The patch name data starts at the
- * address patch + startHere.
- * Each byte of the patch name is followed by a 0 byte.
- */
-
- void PrintPatchName(UBYTE *patch, long startHere)
- {
- int i;
-
- if (patch)
- for (i=0; i<NAME_LENGTH; i++)
- putchar(patch[startHere + (2 * i)]);
- }
-
- /*
- * Given the data for a multi patch, print the single patch numbers that
- * make up that multi patch. The relevant data begins at address
- * patch + startHere. Each patch number byte is followed by a 0 byte.
- */
-
- void PrintSinglesInMulti(UBYTE *patch, long howMany, long startHere)
- {
- int i;
- UBYTE data;
-
- if (patch)
- {
- printf(" <%02d", patch[startHere]);
-
- for (i=1; i<howMany; i++)
- {
- data = patch[startHere + (2*i)];
- printf(" %02d", data);
- }
- printf(">");
- }
- }
-
-
- /*****************************************************************************
- * Verifying patchinfo data.
- *****************************************************************************/
-
- /*
- * Verify that some data is a legal patch. The data begins at address
- * pi->data + offset, and certain bytes must match those expected for
- * an Xpander/Matrix-12 patch dump.
- * Return TRUE if the patch data is valid (else FALSE).
- */
-
- BOOL VerifyPatch(PATCHINFO *pi, long offset)
- {
- UBYTE *startHere = pi->data + offset;
-
- if (startHere[BYTE_SYSEX] != SYSEX_BEGIN)
- ErrorMsg(ERROR_NOTSYSEX);
- else if (startHere[BYTE_ID] != OBERHEIM_SYSEX_ID)
- ErrorMsg(ERROR_NOTOBERHEIM);
- else if (!FigureOutInstrument(pi, startHere[BYTE_DEVICE]))
- ErrorMsg(ERROR_NOTXPMATRIX);
- else if (pi->actualSize != pi->rightSize)
- {
- if (pi->actualSize < pi->rightSize)
- ErrorMsg(ERROR_DATATOOSMALL);
- else
- ErrorMsg(ERROR_DATATOOBIG);
-
- if (ERR_OUTPUT_ALLOWED)
- fprintf(stderr,
- "(%ld bytes were expected, but we have %ld.)\n",
- pi->rightSize, pi->actualSize);
- }
- else if (startHere[BYTE_DATADUMP] != DUMP_FOLLOWS)
- ErrorMsg(ERROR_NOTPATCHDATA);
- else if (startHere[BYTE_PATCHTYPE] != pi->mode)
- ErrorMsg(ERROR_UNKNOWNVOICEDATA);
- else if (startHere[pi->rightSize - 1] != SYSEX_END)
- ErrorMsg(ERROR_NOEOX);
- else
- return(TRUE);
-
- return(FALSE);
- }
-
-
- /*
- * Which instrument did the given PATCHINFO data come from?
- * Only the "mode" is known (single or multi) at this point.
- * Single patch data is identical in (and compatible between) the Xpander
- * and Matrix-12, so we can calculate its expected size, name offset, and
- * instrument name immediately.
- * For a multi patch, we must look at the value of "instrument" to determine
- * if the data is from an Xpander or a Matrix-12, and we fill in the
- * remaining data from there.
- * Return TRUE on success (else FALSE).
- */
-
- BOOL FigureOutInstrument(PATCHINFO *pi, UBYTE instrument)
- {
- if (pi->mode == MODE_SINGLE)
- {
- if (instrument == OBERHEIM_DEVICE_NUMBER)
- {
- pi->rightSize = (long)SINGLE_SIZE;
- pi->nameOffset = (long)SINGLE_NAMELOC;
- strcpy(pi->instrument, NAME_BOTH);
- }
- else
- return(FALSE);
- }
- else if (pi->mode == MODE_MULTI)
- {
- if (instrument == XPANDER_MULTI_ID)
- {
- pi->rightSize = (long)XPANDER_MULTI_SIZE;
- pi->nameOffset = (long)XPANDER_MULTI_NAMELOC;
- strcpy(pi->instrument, NAME_XPANDER);
- pi->numSinglesInside = (long)XPANDER_MULTI_SINGLES;
- pi->firstSingleOffset = (long)XPANDER_SINGLE_OFFSET;
- }
- else if (instrument == MATRIX12_MULTI_ID)
- {
- pi->rightSize = (long)MATRIX12_MULTI_SIZE;
- pi->nameOffset = (long)MATRIX12_MULTI_NAMELOC;
- strcpy(pi->instrument, NAME_MATRIX12);
- pi->numSinglesInside = (long)MATRIX12_MULTI_SINGLES;
- pi->firstSingleOffset = (long)MATRIX12_SINGLE_OFFSET;
- }
- else
- return(FALSE);
- }
- else
- return(FALSE);
-
- return(TRUE);
- }
-